﻿using System;
using System.Text;

namespace Bettzueche.RLGlue.TaskSpec {

    /// <summary>
    /// 
    /// </summary>
    public class DoubleRange : AbstractRange {

        double _min;
        /// <summary>
        /// Gets or sets the lower bound value of this range.
        /// </summary>
        /// <value>
        /// The min value.
        /// </value>
        /// <exception cref="ArgumentException">value = positive Infinity</exception>
        public double Min {
            get { return _min; }
            set {
                if (value == Double.PositiveInfinity)
                    throw new ArgumentException("Min value must not be positiv infinity.");
                _min = value;
            }
        }

        double _max;
        /// <summary>
        /// Gets or sets the upper bound value of this range.
        /// </summary>
        /// <value>
        /// The max value.
        /// </value>
        /// <exception cref="ArgumentException">value = negativ Infinity</exception>
        public double Max {
            get { return _max; }
            set {
                if (value == Double.NegativeInfinity)
                    throw new ArgumentException("Min value must not be negative infinity.");
                _max = value;
            }
        }

        #region Object Overrides
        
        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public override int GetHashCode() {
            return base.GetHashCode() ^ Min.GetHashCode() ^ Max.GetHashCode();
        }

        /// <summary>
        /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
        /// <returns>
        ///   <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public override bool Equals(object obj) {
            DoubleRange other = obj as DoubleRange;
            if (other == null)
                return false;
            return (other.Cardinality == this.Cardinality) &&
                    (other._min == this._min) &&
                    (other._max == this._max);
        }

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString() {
            StringBuilder sb = new StringBuilder("DoubleRange(");
            System.Reflection.PropertyInfo[] props = this.GetType().GetProperties();
            foreach (var prop in props) {
                sb.Append(prop.Name);
                sb.Append('=');
                prop.GetValue(this, null);
                sb.Append(',');
            }
            if (props.Length > 0)
                sb.Remove(sb.Length - 1, 1); // remove last comma
            sb.Append(')');
            return base.ToString();
        }

        #endregion

    }
}
